package com.service.impl;

import com.alibaba.fastjson.JSON;
import com.dao.ManualStrDao;
import com.dao.ReportPublicStrDao;
import com.dao.ReportStrDao;
import com.dao.SearchlibResDao;
import com.model.ReportPublicStr;
import com.model.ReportStr;
import com.model.SearchlibRes;
import com.service.ReportStrService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service(value = "ReportStrService")
public class ReportStrServiceImpl implements ReportStrService {
    private static final Logger log = LoggerFactory.getLogger(ReportStrServiceImpl.class);

    private String error;
    @Autowired
    ReportStrDao reportStrDao;
    @Autowired
    SearchlibResDao searchlibResDao;
    @Autowired
    ReportPublicStrDao reportPublicStrDao;
    @Autowired
    ManualStrDao manualStrDao;

    @Autowired
    CalculateStrService calculateStrService;
    @Autowired
    ReportPublicStrService reportPublicStrService;

    @Override
    public ReportStr selectByPk(int id) {
        return reportStrDao.selectReportStrByPrimaryKey(id);
    }

    @Override
    public ReportStr selectFirstNoCompare() {
        return reportStrDao.selectFirstReportStrNoCompare();
    }

    @Override
    public List<ReportStr> selectReportStrLimitExcludeSelf(int start, int end, int pk) {
        return reportStrDao.selectReportStrLimitExcludeSelf(start, end, pk);
    }

    @Override
    public int count() {
        return reportStrDao.countReportStr();
    }

    @Override
    public List<ReportStr> selectLimit(int start, int limit) {
        return reportStrDao.selectAllReportStrLimit(start, limit);
    }

    @Override
    public void compareStrWithReportStr(String strHash, String str) {
        int limit = 1000;
        int start = 0;
        Map<String, String> strMap = calculateStrService.extractManualStrInfo(str);
        List<ReportStr> reportStrList = selectLimit(start, limit);

        while (reportStrList.size() > 0) {
            List<SearchlibRes> searchlibResList = Collections.synchronizedList(new ArrayList<>());
            for (ReportStr reportStr : reportStrList) {
                Map<String, String> reportStrMap = calculateStrService.getReportStrMap(reportStr);
                if (reportStrMap.size() > 0 && strMap.size() > 0) {
                    int strCount = calculateStrService.getIntersectionNum(strMap,reportStrMap);
                    Double distance = calculateStrService.getDistance(strMap, reportStrMap);
                    Double year = calculateStrService.getYear(strMap, reportStrMap);
                    SearchlibRes searchlibRes = new SearchlibRes();
                    searchlibRes.setMemberId(0);
                    searchlibRes.setStrHash(strHash);
                    searchlibRes.setSourceStrId(0);
                    searchlibRes.setTargetStrId(reportStr.getId());
                    searchlibRes.setTargetLib("inner");
                    searchlibRes.setDistance(distance);
                    searchlibRes.setYear(year);
                    searchlibRes.setStrNum(strCount);
                    searchlibRes.setDistanceVal(distance/strCount);
                    searchlibResList.add(searchlibRes);
                }

            }
            if (searchlibResList.size() > 0) {
                int resInsert = searchlibResDao.bathInsertSearchlibRes(searchlibResList);
                if (resInsert > 0) {
                    log.info("成功插入" + searchlibResList.size() + "条与内部库的比对结果");
                    start += limit;
                    reportStrList = selectLimit(start, limit);
                    if (reportStrList.size() > 0 && reportStrList.get(0).getSampleSn() == null) {
                        reportStrList.clear();
                    }
                }
            }
        }
        int updateRes = manualStrDao.updateManualStrSetStrStatusTrueByStrHash(strHash);
        log.info("更新了结果：" + updateRes);
    }

    @Override
    public void compareStrWithPublicStr(String strHash, String str) {
        int limit = 1000;
        int start = 0;
        Map<String, String> strMap = calculateStrService.extractManualStrInfo(str);
        List<ReportPublicStr> reportPublicStrs = reportPublicStrService.selectReportPublicStrLimit(start, limit);
        while (reportPublicStrs.size() > 0) {
            List<SearchlibRes> searchlibResList = Collections.synchronizedList(new ArrayList<>());
            for (ReportPublicStr reportPublicStr : reportPublicStrs) {
                Map<String, String> reportPublicStrMap = calculateStrService.getPublicStrLib(reportPublicStr);
                if (reportPublicStrMap.size() > 0 && strMap.size() > 0) {
                    int strCount = calculateStrService.getIntersectionNum(strMap,reportPublicStrMap);
                    Double distance = calculateStrService.getDistance(strMap, reportPublicStrMap);
                    Double year = calculateStrService.getYear(strMap, reportPublicStrMap);
                    SearchlibRes searchlibRes = new SearchlibRes();
                    searchlibRes.setMemberId(0);
                    searchlibRes.setStrHash(strHash);
                    searchlibRes.setSourceStrId(0);
                    searchlibRes.setTargetStrId(reportPublicStr.getId());
                    searchlibRes.setTargetLib("out");
                    searchlibRes.setDistance(distance);
                    searchlibRes.setYear(year);
                    searchlibRes.setStrNum(strCount);
                    searchlibRes.setDistanceVal(distance/strCount);
                    searchlibResList.add(searchlibRes);
                }

            }
            if (searchlibResList.size() > 0) {
                int resInsert = searchlibResDao.bathInsertSearchlibRes(searchlibResList);
                if (resInsert > 0) {
                    log.info("成功插入" + searchlibResList.size() + "条与公共库的比对结果");
                    start += limit;
                    reportPublicStrs = reportPublicStrService.selectReportPublicStrLimit(start, limit);
//                    if (reportPublicStrs.size() > 0 && reportPublicStrs.get(0).getSampleName() == null) {
//                        reportPublicStrs.clear();
//                    }
                }
            }
        }
        int updateRes = manualStrDao.updateManualStrSetPublicStatusTrueByStrHash(strHash);
        log.info("更新了结果：" + updateRes);
    }

//    public List<ReportPublicStr> handlePublicStr(List<ReportPublicStr> reportPublicStrList) {
//        List<ReportPublicStr> reportPublicStrList1 = new ArrayList<>();
//        for (ReportPublicStr reportPublicStr : reportPublicStrList) {
//            if (reportPublicStr.getSampleName() != null) {
//                reportPublicStrList1.add(reportPublicStr);
//            }
//        }
//        return reportPublicStrList1;
//    }
    @Override
    public void setError(String error) {
        this.error = error;
    }

    @Override
    public String getError() {
        return error;
    }
}
